package com.edu.buservice.dal.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.edu.buservice.dal.mapper.SysTenantMapper;
import com.edu.buservice.dal.model.SysTenant;
import com.edu.buservice.dal.service.SysTenantService;
import com.edu.buservice.util.model.PageQuery;
import com.edu.buservice.util.model.PageResult;
import com.edu.buservice.util.model.enums.ErrorCodeEnum;
import com.edu.buservice.util.model.error.BizException;
import io.grpc.okhttp.internal.framed.ErrorCode;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
* @author 86177
* @description 针对表【sys_tenant(租户信息表)】的数据库操作Service实现
* @createDate 2025-02-05 23:34:09
*/
@Service
public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant>
    implements SysTenantService{


	@Override
	public SysTenant getTenantInfoByTenantId(String tenantId) {

		LambdaQueryWrapper<SysTenant> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(SysTenant::getTenantId, tenantId);
		queryWrapper.eq(SysTenant::getDeleted, 0);
		queryWrapper.eq(SysTenant::getStatus, 1);

		return getOne(queryWrapper);
	}

	@Override
	public List<SysTenant> batchQueryTenantInfo(List<String> tenantIds) {
		if (tenantIds != null && !tenantIds.isEmpty()) {
			LambdaQueryWrapper<SysTenant> queryWrapper = new LambdaQueryWrapper<>();
			queryWrapper.in(SysTenant::getTenantId, tenantIds);
			queryWrapper.eq(SysTenant::getDeleted, 0);
			queryWrapper.eq(SysTenant::getStatus, 1);
			return list(queryWrapper);
		}
		return List.of();
	}

	@Override
	public Boolean createTenant(String tenantId, String tenantName) {

		SysTenant sysTenant = new SysTenant();
		sysTenant.setTenantId(tenantId);
		sysTenant.setName(tenantName);
		sysTenant.setCreatedBy(StpUtil.getLoginIdAsString());
		sysTenant.setUpdatedBy(StpUtil.getLoginIdAsString());
		sysTenant.setStatus(1);
		sysTenant.setDeleted(0);
		sysTenant.setToken(0L);
		sysTenant.setCreatedAt(new Date());
		sysTenant.setUpdatedAt(new Date());
		return save(sysTenant);

	}

	@Override
	public PageResult<SysTenant> queryTenant(PageQuery<SysTenant> pageQuery) {

		//获取分页大小与当前页，默认1
		Long size = Optional.ofNullable(pageQuery.getPageSize()).orElse(10L);
		Long current = Optional.ofNullable(pageQuery.getPageNum()).orElse(1L);

		LambdaQueryWrapper<SysTenant> queryWrapper = new LambdaQueryWrapper<>();

		SysTenant query = pageQuery.getQuery();
		if(query != null){

			if(StrUtil.isNotBlank(query.getTenantId())){
				queryWrapper.eq(SysTenant::getTenantId, query.getTenantId());
			}

			if(StrUtil.isNotBlank(query.getName())){
				queryWrapper.like(SysTenant::getName, query.getName());
			}

			if(query.getStatus() != null){
				queryWrapper.eq(SysTenant::getStatus, query.getStatus());
			}

		}

		queryWrapper.eq(SysTenant::getDeleted, 0);

		queryWrapper.orderByDesc(SysTenant::getCreatedAt);

		IPage<SysTenant> pageParam = new Page<>(current, size);

		IPage<SysTenant> pageResult = page(pageParam, queryWrapper);

		if (Objects.isNull(pageResult)){
			throw new RuntimeException("数据库查询失败");
		}

		PageResult<SysTenant> res = new PageResult<>();
		res.setTotal(pageResult.getTotal());
		res.setTotalPages(pageResult.getPages());
		res.setCurrentPage(pageResult.getCurrent());
		res.setRecords(pageResult.getRecords());
		return res;
	}

	@Override
	public Boolean updateTenant(SysTenant tenant) {

		if (tenant.getTenantId() == null){
			throw new BizException(ErrorCodeEnum.PARAM_MISSING);
		}

		LambdaUpdateWrapper<SysTenant> updateWrapper = new LambdaUpdateWrapper<>();
		updateWrapper.eq(SysTenant::getTenantId, tenant.getTenantId());

		Optional.ofNullable(tenant.getName()).ifPresent(name -> updateWrapper.set(SysTenant::getName,name));

		Optional.ofNullable(tenant.getStatus()).ifPresent(status -> updateWrapper.set(SysTenant::getStatus,status));

		updateWrapper.set(SysTenant::getUpdatedAt, new Date());

		updateWrapper.set(SysTenant::getUpdatedBy, StpUtil.getLoginIdAsString());

		return update(updateWrapper);
	}

	/**
	* @Description: 缺少乐观锁失败重试
	* @Param: [tenantId, token]
	* @return: java.lang.Boolean
	* @Author: 范铁凝
	* @Date: 2025/5/4
	*/

	@Override
	public Boolean updateTenantToken(String tenantId, Long token) {
		//先查询目前token
		SysTenant sysTenant = getTenantInfoByTenantId(tenantId);

		if (Objects.isNull(sysTenant)){
			throw new BizException(ErrorCodeEnum.DATA_NOT_FOUND);
		}

		Long currentToken = sysTenant.getToken();

		//token累加
		Long newToken = currentToken + token;

		//乐观锁更新
		LambdaUpdateWrapper<SysTenant> updateWrapper = new LambdaUpdateWrapper<>();
		updateWrapper.eq(SysTenant::getTenantId, tenantId);
		updateWrapper.eq(SysTenant::getToken, currentToken);
		updateWrapper.set(SysTenant::getToken, newToken);
		updateWrapper.set(SysTenant::getUpdatedAt, new Date());

		return update(updateWrapper);

	}
}




